【z3 实践】【buu】[GWCTF 2019]xxor
拖进 ida 中
跟进 main
发现是输入的字符串经过一个 魔改 tea 加密与检查函数
跟进魔改 tea,发现只是将 delta 和异或部分多加了点东西
跟进 sub_400700
感觉要爆破
因为 v6 是 int64,所以要设置成 64 位
爆破脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| from z3 import *
enc = [0]*6 for i in range(6): enc[i] = BitVec('enc['+str(i)+']',64) flag = BitVec('flag', 64)
s = Solver() s.add(enc[2] - enc[3] == 0x84A236FF) s.add(enc[3] + enc[4] == 0xFA6CB703) s.add(enc[2] - enc[4] == 0x42D731A8) s.add(enc[0] == 0xDF48EF7E) s.add(enc[5] == 0x84F30420) s.add(enc[1] == 0x20CAACF4)
if s.check() == sat: print("6666") m = s.model() for i in range(6): print("enc["+str(i)+"] =", hex(m[enc[i]].as_long()))
else: print("wrong")
print (hex(0x458BCD42 * 64))
|
爆破完得到密文
进行解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include <iostream> using namespace std;
void decrypt (uint32_t* v, uint32_t* k) { uint32_t v0, v1; uint32_t delta=0x458BCD42; uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; for (int j = 0; j <= 4; j += 2) { uint32_t sum=0x458BCD42 * 0x40 ; v0 = v[j]; v1 = v[j + 1]; for (int i=0; i<64; i++) { v1 -= ((v0<<6) + k2) ^ (v0 + sum + 20) ^ ((v0>>9) + k3) ^ 0x10; v0 -= ((v1<<6) + k0) ^ (v1 + sum + 11) ^ ((v1>>9) + k1) ^ 0x20; sum -= delta; } v[j]=v0; v[j+1]=v1; } }
int main() { uint32_t v[6]={0xdf48ef7e,0x20caacf4,0xe0f30fd5,0x5c50d8d6,0x9e1bde2d,0x84f30420},k[4]={0x02,0x02,0x03,0x04};
decrypt(v, k); for (int i = 0; i < 6; ++i) {
printf("%llx", v[i]); } return 0; }
|
因为计算出来的是 16 进制,所以把 16 进制输出后需要进行转换称为字符串·